package com.ky.manage;

import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Intent;
import android.os.StrictMode;
import android.util.Log;

import com.github.anrwatchdog.ANRWatchDog;
import com.ky.manage.activity.LoginActivity;
import com.ky.manage.activity.PwdLoginActivity;
import com.ky.manage.activityLifecycle.CommonActivityLifecycleCallbacksImp;
import com.ky.manage.base.BaseActivity;
import com.ky.manage.constant.OverallData;
import com.ky.manage.model.LoginUserInfo;
import com.ky.manage.utils.MMKVUtil;
import com.ky.manage.utils.ScreenUtils;
import com.ky.manage.utils.SharedPreferencesUtil;
import com.ky.manage.utils.ToastUtils;
import com.ky.manage.utils.Utils;
import com.ky.manage.utils.ZyUtils;
import com.tencent.smtt.export.external.TbsCoreSettings;
import com.tencent.smtt.sdk.QbSdk;

import org.greenrobot.eventbus.EventBus;

import java.io.Serializable;
import java.util.HashMap;

import xcrash.ICrashCallback;
import xcrash.XCrash;


@SuppressLint("Registered")
public class BaseApplication extends Application implements Serializable {
    /**
     * 设置监听anr
     */
    private static final int ANR_TIME_OUT_INTERVAL = 8000;
    private static Application mApp;

    /**
     * 获取应用程序context
     *
     * @return
     */
    public static Application getContext() {
        return mApp;
    }

    /*
     *项点信息回调
     */
    @SuppressLint("UseSparseArrays")
    @Override
    public void onCreate() {
        //严苛模式设置
        setStrictMode();
        super.onCreate();
        init();
    }

    private void init() {
        setGlobalFields();
        //初始化屏幕参数
        ScreenUtils.initScreen(this);
        //初始化xcrash拦截库
        initXcrash();
        //监听anr
        watchANR();
        //注册生命周期
        registerActivityLifecycle();
        //初始化Toast
        ToastUtils.init(this);
        initX5Webview();
        ZyUtils.getInstance().registerNetworkCallback();
    }

    private void initX5Webview() {
        //搜集本地tbs内核信息并上报服务器，服务器返回结果决定使用哪个内核。
        QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
            @Override
            public void onViewInitFinished(boolean arg0) {
                // TODO Auto-generated method stub
                //x5內核初始化完成的回调，为true表示x5内核加载成功，否则表示x5内核加载失败，会自动切换到系统内核。
                Log.d("app", " onViewInitFinished is " + arg0);
            }

            @Override
            public void onCoreInitFinished() {
                // TODO Auto-generated method stub
            }
        };
        //x5内核初始化接口
        QbSdk.initX5Environment(getApplicationContext(),  cb);
        //设置开启优化方案
        HashMap map = new HashMap();
        map.put(TbsCoreSettings.TBS_SETTINGS_USE_SPEEDY_CLASSLOADER, true);
        map.put(TbsCoreSettings.TBS_SETTINGS_USE_DEXLOADER_SERVICE, true);
        QbSdk.initTbsSettings(map);
    }

    private void watchANR() {
        if (BuildConfig.DEBUG) {
            return;
        }
        new ANRWatchDog(ANR_TIME_OUT_INTERVAL) //默认5000ms
                .setIgnoreDebugger(true) //debugger模式下anr忽略，不回调
                .setReportMainThreadOnly()
                .setANRInterceptor(duration -> {
                    //anr拦截器（anr真正触发前的处理）
                    long ret = ANR_TIME_OUT_INTERVAL - duration;//小于8s触发anr则再延迟ret ms响应anr（即8s内不触发）
                    //ret <= 0 立即触发anr
                    return ret;
                })
                .setANRListener(error -> {
                    //anr触发回调
                    //重启应用
                    Utils.collectANRError(error);
                    Utils.restartApplication();
                }).start();
    }

    /**
     * 严苛模式设置:只在调试包使用
     */
    private void setStrictMode() {
        if (BuildConfig.DEBUG) {
            StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
            StrictMode.setVmPolicy(builder.build());
        }
    }

    /**
     * 注册activity生命周期
     */
    private void registerActivityLifecycle() {
        registerActivityLifecycleCallbacks(new CommonActivityLifecycleCallbacksImp());
    }

    /**
     * 初始化相关全局变量
     */
    private void setGlobalFields() {
        mApp = this;
        OverallData.app = mApp;
    }

    /**
     * 初始化xCrash拦截库
     */
    private void initXcrash() {
        // callback for java crash, native crash and ANR
        ICrashCallback callback = (logPath, emergency) -> {
//            Log.d("zhaoyan", "Xcrash log path: " + (logPath != null ? logPath : "(null)")
//                    + ", emergency: " + (emergency != null ? emergency : "(null)"));
            //保存崩溃日志：xCrashLx目录下
            //tombstone_00001607319667144000_V1.2.0.8891__lxkj.train.com.java
            //tombstone_00001607319639977781_V1.2.0.8891__lxkj.train.com.anr
            //tombstone_00001607319470733651_V1.2.0.8891__lxkj.train.com.native
            Utils.restartApplication();
        };
        XCrash.init(this, new XCrash.InitParameters()
                .setAppVersion("zy_ky_" + BuildConfig.VERSION_NAME)
                //是否抛出Java异常
                .setJavaRethrow(false)
                //java异常文件数量
                .setJavaLogCountMax(10)
                .setJavaDumpAllThreadsWhiteList(new String[]{"^main$", "^Binder:.*", ".*Finalizer.*"})
                .setJavaDumpAllThreadsCountMax(10)
                .setJavaCallback(callback)
                //是否抛出异常
                .setNativeRethrow(false)
                .setNativeLogCountMax(10)
                .setNativeDumpAllThreadsWhiteList(new String[]{"^xcrash\\.sample$", "^Signal Catcher$", "^Jit thread pool$", ".*(R|r)ender.*", ".*Chrome.*"})
                .setNativeDumpAllThreadsCountMax(10)
                .setNativeCallback(callback)
                //是否抛出异常
//                .setAnrRethrow(false)
//                .setAnrLogCountMax(10)
//                .setAnrCallback(callback)
                //异常输出日志目录
                .setLogDir(OverallData.sdkPath + "zyXCrash")
                // 初始化xCrash后延迟xx毫秒，进行日志文件维护任务（为清理多余的过期日志文件）
                .setLogFileMaintainDelayMs(1000));
    }

    /**
     * 判断是否登录且登录有效
     * @return
     */
    public static boolean isValidLogin() {
        return isValidLogin(null, false);
    }

    /**
     * 未登陆跳转登陆页
     * @param baseActivity
     * @param needJump2Login
     * @return
     */
    public static boolean isValidLogin(BaseActivity baseActivity, boolean needJump2Login) {
        boolean isLogin = null != getLoginUserInfo();
        if (!isLogin && needJump2Login && null != baseActivity) {
            baseActivity.toActivity(new Intent(baseActivity, OverallData.sEnableSmsCodeLogin ?
                    LoginActivity.class : PwdLoginActivity.class));
        }
        return isLogin;
    }

    /**
     * 更新用户信息
     * @param userInfo
     */
    public static void updateLoginUserInfo(LoginUserInfo userInfo) {
        if (null == userInfo) {
            //退出登录
            MMKVUtil.getInstance().removeKey("userInfo");
            MMKVUtil.getInstance().removeKey("token");
            SharedPreferencesUtil.saveStringData("token", "");
            EventBus.getDefault().post(new LoginUserInfo(false));
        } else {
            //登录成功
            MMKVUtil.getInstance().saveObjectToMMKV("userInfo", userInfo);
            EventBus.getDefault().post(userInfo);
        }
    }

    public static LoginUserInfo getLoginUserInfo() {
        return MMKVUtil.getInstance().readObjectFromMMKV("userInfo", LoginUserInfo.class);
    }
}
